Skip to content

gh-155027: Make test_asyncio's socket harness able to fail a test - #155028

Open
matthiasgoergens wants to merge 1 commit into
python:mainfrom
matthiasgoergens:matthias/fix-asyncio-abort-socket-test
Open

gh-155027: Make test_asyncio's socket harness able to fail a test#155028
matthiasgoergens wants to merge 1 commit into
python:mainfrom
matthiasgoergens:matthias/fix-asyncio-abort-socket-test

Conversation

@matthiasgoergens

@matthiasgoergens matthiasgoergens commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

_abort_socket_test() called self.fail() from the client or server thread. self.fail() raises AssertionError in the calling thread, and both call sites are inside a Thread.run(), so the exception escapes the thread without ever reaching TestCase.run() — the test still reports ok. This patch records the exception instead and re-raises it from tearDown(), on the main thread, where unittest can see it.

It also replaces self.loop.stop() with self.loop.call_soon_threadsafe(self.loop.stop). Event loops are not thread-safe and this call was being made from a non-main thread.

Background, measurements and the history are in #155027. In short: this has never worked in any release since 3.7, and since 3.10 the only thing that notices is regrtest's threading excepthook, which wins the race roughly half the time.

Verification

Same binary, the patch toggled on and off, running a test whose server prog raises ConnectionResetError — the shape of the Windows CI failure that prompted this:

exit status regrtest verdict
stock main 0 SUCCESS (recorded only as "env changed")
with this patch 2 FAILURE — 1 test failed

The test module used is not included here; see "open question" below.

Please treat this as potentially disruptive

I would rather flag this clearly than have it discovered on the buildbots.

The diff is small but its effect is not local. These failures currently do not fail tests, so making the abort work means any latent failure in the client or server half of a socket test will start failing. The mixin is used by test_sslproto, test_ssl, test_events, test_server, test_streams, test_buffered_proto, test_sock_lowlevel and test_unix_events.

What I can say from here: test_asyncio is green on Linux with the patch, 2,819 tests, five consecutive runs, no flakes.

What I cannot say: anything about the other platforms, and that is where the risk actually is. The failure that prompted this was Windows-only, and I expect it to go red. Platform-specific socket behaviour is precisely what a Linux dev box cannot tell you about, and eight years of accumulated silence is a lot of surface to uncover at once.

So I am not assuming this should merge as-is. Reasonable alternatives, if maintainers prefer: land it early in a release cycle rather than near a beta; or land the diagnosis first, see what turns red across the buildbot fleet, fix those, and enable the abort afterwards. I am happy to split it that way, or to drop it if the churn is not judged worth the benefit.

Open question for reviewers

I have not added a regression test. A natural one would assert that a failing server prog fails the test, but it would have to do so by asserting that a test fails, which needs care to write well in this suite. Happy to add one in whatever form is preferred — or to leave it, given that the change is itself test-infrastructure.

_abort_socket_test() called self.fail() from the client/server thread.
The resulting AssertionError escapes Thread.run() without ever reaching
TestCase.run(), so an error in the server half of a socket test did not
fail it. Record the exception instead and re-raise it from tearDown().

Also stop the event loop with call_soon_threadsafe() rather than calling
loop.stop() directly from a non-main thread.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant